// Copyright (c) 2010-2014 SharpDX - Alexandre Mutel
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//------------------------------------------------------------------------------
// <auto-generated>
//     Types declaration for CorApi.Portable namespace.
//     This code was generated by a tool.
//     Date : 09/05/2017 20:38:52
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Runtime.InteropServices;
using System.Security;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
#if true
namespace CorDebug
{
#pragma warning disable 649
#pragma warning disable 419
#pragma warning disable 1587
#pragma warning disable 1574

    internal partial class LocalInterop
    {
        static T CreateCaller<T>()
        {
            var sig = typeof(T).GetTypeInfo().GetMethod("Invoke");
            var prms = sig.GetParameters().Select(p => p.ParameterType).ToArray();


            var dm = new System.Reflection.Emit.DynamicMethod("Caller", sig.ReturnType, prms, typeof(LocalInterop).GetTypeInfo().Assembly.ManifestModule);
            var gen = dm.GetILGenerator();
            for (var c = 1; c < prms.Length; c++)
                gen.Emit(OpCodes.Ldarg, c);
            gen.Emit(OpCodes.Ldarg_0);
            gen.EmitCalli(OpCodes.Calli, CallingConventions.Standard, sig.ReturnType, prms.Skip(1).ToArray(), null);

            gen.Emit(OpCodes.Ret);
            return (T)(object)dm.CreateDelegate(typeof(T));
        }

        static class Calli<TRet, TArg1>
        {
            public delegate TRet Call(IntPtr pointer, TArg1 arg1);
            public static readonly Call Invoke = CreateCaller<Call>();
        }

        static class Calli<TRet, TArg1, TArg2>
        {
            public delegate TRet Call(IntPtr pointer, TArg1 arg1, TArg2 arg2);
            public static readonly Call Invoke = CreateCaller<Call>();
        }

        static class Calli<TRet, TArg1, TArg2, TArg3>
        {
            public delegate TRet Call(IntPtr pointer, TArg1 arg1, TArg2 arg2, TArg3 arg3);
            public static readonly Call Invoke = CreateCaller<Call>();
        }

        static class Calli<TRet, TArg1, TArg2, TArg3, TArg4>
        {
            public delegate TRet Call(IntPtr pointer, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4);
            public static readonly Call Invoke = CreateCaller<Call>();
        }

        private unsafe delegate int voidDelegate(void* thisPtr);
        private unsafe delegate int arg2Delegate(void* thisPtr, void* arg0, void* arg1);

        public static unsafe int Calliint(void* thisObject, void* methodPtr)
        {
            return Calli<int, IntPtr>.Invoke((IntPtr)methodPtr, (IntPtr)thisObject);
        }

        public static unsafe int Calliint(void* thisObject, void* arg0, void* arg1, void* methodPtr)
        {
            return Calli<int, IntPtr, IntPtr, IntPtr>.Invoke((IntPtr)methodPtr, (IntPtr)thisObject, (IntPtr)arg0, (IntPtr)arg1);
        }
    }
}
#endif
